AoC problems are misleading on purpose
Today is a simple map manipulation task. It's not particularly difficult I would say; it's just, implementing it the way the problem statement leads you to is insanely inefficient.
It's about domain space expansion. All you have to do is find empty rows/columns, double them in size, and then find the sum of lengths of the shortest paths between each pair of stars on the map.
Ok, but don't actually do it that way. Don't actually expand the map. Also, don't actually try to find the shortest path. It's just taxicab distance, because there's never any obstacles.
To deal with the empty columns and rows, I wrote this helper:
fn indices_to_map(count: usize, expansion: usize, indices: &[usize]) -> Vec<usize> {
let mut map = vec![0; count];
let mut taken = 0;
for (i, m) in map.iter_mut().enumerate() {
if let Some(&skip) = indices.get(taken) {
if skip == i {
taken += 1;
}
}
*m = i + taken * expansion;
}
map
}
count
is the width of the map (if doing empty columns) or the height of the map (if doing empty rows). indices
is the, well, indices of the empty columns or rows. expansion
is how many empty rows/columns we are adding (mild spoiler for where part 2 is going I guess, lol).
The idea is that we can then simply take this returned array and index it to find our "actual" position with space expansion taken into account. For the example:
...#......
.......#..
#.........
..........
......#...
.#........
.........#
..........
.......#..
#...#.....
let x_map = indices_to_map(map[0].len(), 1, &empty_columns);
let y_map = indices_to_map(map.len(), 1, &empty_rows);
We can see that this is a 10x10 map with empty columns at x = 2
, x = 5
, x = 8
. My helper method would produce x_map = [0, 1, 3, 4, 5, 7, 8, 9, 11, 12]
. So if x
is the x-coordinate actual spot on the map, x_map[x]
is the coordinate after taking space expansion into account.
Now that the whole space expansion stuff is abstracted away, finding the sums of all pairs is fairly easy.
Having done all this due dilligence, part 2 is very simple. It asks you to expand empty rows/columns a million times. Physically altering the map wouldn't really work with this... but now it's simply a matter of changing the number when building my mappings:
let x_map = indices_to_map(map[0].len(), 999999, &empty_columns);
let y_map = indices_to_map(map.len(), 999999, &empty_rows);
(It's 999999 because we give it 1 less than what we want to multiply space by, since one row/column already exists. Just like we expanded by 1 to double in part 1.)
Literally nothing else changes about my code. Nice.